package com.dldata.devtools30.utils;

import com.alibaba.fastjson.JSON;
import com.dldata.devtools30.entity.*;
import com.dldata.devtools30.repository.common.hib.BeanPropertyRowMapperDl;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.SocketConfig;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.request.ServletWebRequest;

import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
/**

 */
public class Public {
    
    /**
     * API日志保留天数
     */
    public static int logstoredays=15;
    
    /**
     * 扩展备份
     */
    public final static ArrayList configTableEntitysExt=new ArrayList();
    
    /**
     * devtools表单备份
     */
    public final static Class[] configTableEntitys=new Class[]{
            DevtModelMetadataFieldEntity.class,
            DevtModelMetadataTableEntity.class,
            DevtModelMetadataTypeEntity.class,
            DevtModelOrganizationEntity.class,
            DevtModelReleaselogEntity.class,
            
            DevtFormDesignEntity.class,
            DevtFormFieldcheckEntity.class,
            DevtFormFieldConfigEntity.class,
            DevtFormListtemplArgsEntity.class,
            DevtFormListtemplateEntity.class,
            DevtFormListtemplConfigEntity.class,
            DevtFormListtemplOtherBtnEntity.class,
            DevtFormListtemplTheaderEntity.class,
            DevtFormMetadataEntity.class,
            DevtFormTypeEntity.class,
        
            DevtApiMainEntity.class,
            DevtApiSubEntity.class,
            DevtApiTjoptcheckEntity.class,
            DevtApiTjoptEntity.class,
            DevtApiTypeEntity.class,
            
            DevtZbobjInfoEntity.class,
            DevtZbobjFieldEntity.class,
            DevtZbclassInfoEntity.class,
            DevtZbcfgInfoEntity.class,
        
            DevtZbplanInfoEntity.class,
            DevtZbplanItemEntity.class,
            DevtZbplanParaEntity.class,
            DevtZbplanParatjEntity.class,
            DevtZbplanTypeEntity.class,
            DevtZbplanZbobjEntity.class,

            DevtExcelEntity.class,
            DevtExcelFieldEntity.class,
            DevtExcelTypeEntity.class,
//            DevtExcelLogEntity.class,
            
    };
    
    public final static String[] configtablenames=new String[]{
//            "p_functionconfigform",
//            "p_functionmain",
//            "p_functionsub",
//            "p_functionsub_history",
//            "p_functionsubext",
//            "p_functiontjopt",
//            "p_functiontjopt_history",
//            "p_functiontjoptcheck",
//            "p_functiontype",
//            "p_interfacelog",
            "sys_cfg_setting",
//            "sys_crf_form_design",
//            "sys_crf_form_design_fieldconfig",
//            "sys_crf_form_excelfield",
//            "sys_crf_form_field_template",
//            "sys_crf_form_field_templsubtab",
//            "sys_crf_form_fieldcheck",
            "sys_crf_form_file",
//            "sys_crf_form_listtempl_args",
//            "sys_crf_form_listtempl_config",
//            "sys_crf_form_listtempl_otherbtn",
//            "sys_crf_form_listtempl_theader",
//            "sys_crf_form_listtemplate",
//            "sys_crf_form_metadata",
//            "sys_crf_form_metadata_field",
//            "sys_crf_form_metadata_table",
//            "sys_crf_form_metadata_type",
//            "sys_crf_form_organization",
//            "sys_crf_form_releaselog",
//            "sys_crf_form_template",
//            "sys_crf_form_type",
            "sys_crf_metadata_field",
            "sys_crf_metadata_table",
            "sys_crf_metadata_type",
            
    };
    
    public final static HttpServletRequest getRequest() {
        return ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
    }

    public final static HttpServletResponse getResponse() {
        if(RequestContextHolder.getRequestAttributes() instanceof ServletWebRequest){
            return ((ServletWebRequest)RequestContextHolder.getRequestAttributes()).getResponse();
        }else{
            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            try {
                Method method=
                requestAttributes.getClass().getMethod("getResponse",new Class[]{});
                return (HttpServletResponse)method.invoke(requestAttributes,new Class[]{});
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return ((ServletWebRequest)RequestContextHolder.getRequestAttributes()).getResponse();
    }

    public final static  ServletContext getServletContext() {
        return ContextLoader.getCurrentWebApplicationContext().getServletContext();
    }

    public final static  WebApplicationContext getWebApplicationContext() {
        return ContextLoader.getCurrentWebApplicationContext();
    }

    /**
     * 验证码有效时长
     */
    public static int SMSCODEVALIDTIMELEN = 60*3;

    /**
     * 分页容量最大值
     */
    public final static  int FENYEMAX = 6000;

    /**
     * 多SQL分隔符
     */
    public final static String SQLSPLIT = "90C18768-611E-4752-BE6D-408476E59B6B-SPLIT";

    /**
     *系统可以用来定时执行可以重复的线程池
     */
    public final static ScheduledThreadPoolExecutor SCHEDULEDTHREADPOOLEXECUTOR =(ScheduledThreadPoolExecutor)Executors.newScheduledThreadPool(6);

    /**
     * token加密密钥主体
     */
    public final static String TOKEN_PRINCIPALNAME="admin@dldata.cn";

    /**
     * token加密密钥
     */
    public final static String TOKEN_KEYPASSWORD="admin@dldata.cn";

    /**
     * token有效时长 秒
     */
    public static int TOKEN_VALIDTIMELEN=86400 * 3*10;


    /**
     * 通用接口日志保存目录
     */
    public final static String INTERFACELOG="/static/interfacelog";

    /**
     * 验证码
     */
    public final static String YZM_KEY="REG_VAL_CODE";

    /**
     * sesssion cookie的当前用户key，使用json可以代替前两个cookie
     */
    public static String SESSION_USER_KEY="devuser";
    
    /**
     * 通用API自动备份目录
     */
    public static String commapibackupdir="commapibackup";



    public static final String sqlZhuru = "(?:')|(?:--)|(/\\*(?:.|[\\n\\r])*?\\*/)|(\\b(select|update|and|or|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute)\\b)";
    
    
    /**
     * 指标SQL计算模型提取
     */
    public static final String REG_FIELD_ZH="\\[{1}[\\S]+?\\.{1}[\\S]+?\\]{1}";

    public static final Properties sysConfig=new Properties();

    public static final String image_dir="image_dir";
    public static final String image_dir_bi="/devtools/uploadfiles/";
    public static final String image_dir_default="/devtoolsDefault/uploadfiles/";
    public static final String webapp_dir_ext="/dist/";
    
    public static final String uploadfilerename="uploadfilerename";

    public static final String image_url="image_url";

    public static CloseableHttpClient httpclient = HttpClientBuilder.create()
            .setDefaultSocketConfig(SocketConfig.custom()
                    .setSoKeepAlive(true)
                    .build())
            .setDefaultRequestConfig(RequestConfig.custom()
                    .setSocketTimeout(6000)
                    .setConnectTimeout(6000)
                    .setConnectionRequestTimeout(6000)
                    .setStaleConnectionCheckEnabled(true)
                    .build())
            .build();

    public static <T> BeanPropertyRowMapper<T> newRowMapperInstance(Class<T> mappedClass) {
        BeanPropertyRowMapper<T> newInstance = new BeanPropertyRowMapperDl<T>();
        newInstance.setMappedClass(mappedClass);
        return newInstance;
    }

    public static <T> BeanPropertyRowMapper<T> newRowMapperInstance(Class<T> mappedClass, Charset charset) {
        BeanPropertyRowMapper<T> newInstance = new BeanPropertyRowMapperDl<T>();
        newInstance.setMappedClass(mappedClass);
        ((BeanPropertyRowMapperDl<T>) newInstance).setCharset(charset);
        return newInstance;
    }

    public static int getRandomInt(int min,int max){
        return  min+(int)(Math.random()*(max+1-min));
    }

    public static Thread[] findAllThread(){
        ThreadGroup currentGroup =Thread.currentThread().getThreadGroup();

        while (currentGroup.getParent()!=null){
            // 返回此线程组的父线程组
            currentGroup=currentGroup.getParent();
        }
        //此线程组中活动线程的估计数
        int noThreads = currentGroup.activeCount();

        Thread[] lstThreads = new Thread[noThreads];
        //把对此线程组中的所有活动子组的引用复制到指定数组中。
        currentGroup.enumerate(lstThreads);

        for (Thread thread : lstThreads) {
            System.out.println("线程数量："+noThreads+" 线程id：" + thread.getId() + " 线程名称：" + thread.getName() + " 线程状态：" + thread.getState());
        }
        return lstThreads;
    }

    public static void stopAllThread(int flag){
        Thread[] threadsAry=
                Public.findAllThread();
        List<Thread.State> stateList=new LinkedList<>();
        stateList.add(Thread.State.BLOCKED);
        stateList.add(Thread.State.NEW);
        stateList.add(Thread.State.RUNNABLE);
        stateList.add(Thread.State.TIMED_WAITING);
        stateList.add(Thread.State.WAITING);
        for (int i = 0; i < threadsAry.length; i++) {
            Thread thread = threadsAry[i];
            if(!thread.isDaemon()&&thread.isAlive()&&stateList.contains(thread.getState())){
                thread.setDaemon(true);
            }
            try {
                if(flag>1&&thread.isAlive()&&stateList.contains(thread.getState()))
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }


    public static byte[] readInputStream(InputStream inputStream) throws IOException {
        String s=null;
        ByteArrayOutputStream stringBuilder=new ByteArrayOutputStream();
        byte[] bytesTmp=new byte[10240];
        int inum=-1;
        while((inum=inputStream.read(bytesTmp))!=-1){
            stringBuilder.write(bytesTmp,0,inum);
        }
        return stringBuilder.toByteArray();
    }

    public static String readInputStream(InputStream inputStream,Charset charset) throws IOException {
        return new String(readInputStream(inputStream),charset);
    }


    public static char getRadix(int value){
//        if(value>radix){
//            throw new RuntimeException("value "+value+" biger then radix "+radix);
//        }
//        if(radix>36+26+30){
//            throw new RuntimeException("value "+value+", radix "+radix+" is too big. max radix is 92.");
//        }
        if(value<36){
            return Long.toString(value,36).toLowerCase().charAt(0);
        }
        if(value<36+26){
            return (char)( 'A'+value-36);
        }
//        String valuetemple="`-=[];',./~!@#$%^&*()_+{}|:<>?";
        return getRadioStr().charAt(value-36-26);
    }

    private static String getRadioStr() {
        return "-=@#$%&*_+/!<>{}|:;?,.[]`'~^";
    }

    public static int toRadixValue(char value){
        if(getRadioStr().indexOf(value)!=-1){
            return getRadioStr().indexOf(value)+36+26;
        }
        if(value>='A'&&value<='Z'){
            return value-'A'+36;
        }
        return Integer.parseInt(""+value,36);
    }

    public static byte[] fromEncodeStr(String miwen,Integer radix) {
        BigInteger bigInteger92= BigInteger.valueOf(radix==null?73L:radix);
        BigInteger bigIntegerTmp=new BigInteger("0");
        BigInteger bigInteger =new BigInteger("1");
        int i=0;
        while(i<miwen.length()){
            bigInteger = i==0?bigInteger:bigInteger.multiply(bigInteger92);
            BigInteger multiply = BigInteger.valueOf(toRadixValue(miwen.charAt(i))).multiply(bigInteger);
            bigIntegerTmp=bigIntegerTmp.add(multiply);
            i++;
        }
//        System.out.println(bigIntegerTmp.toString());
        byte[] decode =(bigIntegerTmp.toByteArray());
        return decode;
    }

    public static String toEncodeStr(byte[] miwenByte,Integer radix) {
        BigInteger bigInteger = new BigInteger(1,miwenByte);
        BigInteger bigInteger92 = BigInteger.valueOf(radix==null?73L:radix);
        StringBuilder stringBuilder = new StringBuilder();
        BigInteger[] bigIntegerAry = null;
        BigInteger bigInteger1 = new BigInteger("0");
        do {
            bigIntegerAry = bigInteger.divideAndRemainder(bigInteger92);
            stringBuilder.append(getRadix(bigIntegerAry[1].intValue()));
            bigInteger = bigIntegerAry[0];
        } while (bigInteger.compareTo(bigInteger1) > 0);
        return stringBuilder.toString();
    }

    public static String randomUUIDUpperCase() {
        return UUID.randomUUID().toString().replaceAll("-","").toUpperCase();
    }

    public static String randomUUIDLowerCase() {
        return UUID.randomUUID().toString().replaceAll("-","").toLowerCase();
    }

    public static int iPToInt(String ip) {
        ip = ip.trim();
//        String regular = "([1-9]|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}";
        String[] iparray = ip.split("\\.");
//        if (!ip.matches(regular) || iparray.length != 4){
//            throw new Exception("Wrong IP.");
//        }
        return Integer.parseInt(iparray[0]) << 24 | Integer.parseInt(iparray[1]) << 16
                | Integer.parseInt(iparray[2]) << 8 | Integer.parseInt(iparray[3]);
    }

    public static String intToIP(int ipnum){
        return (int) ((ipnum & 0xff000000L) >> 24) + "." + (int) ((ipnum & 0xff0000L) >> 16) + "."
                + (int) ((ipnum & 0xff00L) >> 8) + "." + (int) (ipnum & 0xffL);
    }

    public static void main(String[] args) {
        String str="1";
        System.out.println("md5: "+MD5Util.MD5Encoder(str.getBytes()));
        String toEncodeStr = toEncodeStr(str.getBytes(),null);
        System.out.println("toEncodeStr: "+toEncodeStr);
        byte[] fromEncodeStr = fromEncodeStr(toEncodeStr,null);
        System.out.println("md5: "+MD5Util.MD5Encoder(fromEncodeStr));
//        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(50);
        for (int i = 10000; i < 100010; i++) {
            try {
                HttpPost httpPost=new HttpPost("http://localhost:18016/DevtFormDesignEntityController/toPreviewSave?1=1&tempid=9d6be830-893c-4742-82b8-46d96f70abd6");
    
//                ContentType.APPLICATION_JSON
                List<String> hashMapList=new ArrayList<>();
                HashMap hashMapid=new HashMap();
                hashMapid.put("id","TEST_JSON_TABLE@ID");
                hashMapid.put("value","");
                hashMapList.add(JSON.toJSONString(hashMapid));
                
                HashMap hashMapname=new HashMap();
                hashMapname.put("id","TEST_JSON_TABLE@NAME");
                hashMapname.put("value","testNAME"+i);
                hashMapList.add(JSON.toJSONString(hashMapname));
                HashMap hashMapcode=new HashMap();
                hashMapcode.put("id","TEST_JSON_TABLE@CODE");
                hashMapcode.put("value","testCODE"+i);
                hashMapList.add(JSON.toJSONString(hashMapcode));
                
                List parameters=new ArrayList<>();
                BasicNameValuePair basicNameValuePair=new BasicNameValuePair("strlist",JSON.toJSONString(hashMapList));
                parameters.add(basicNameValuePair);
                UrlEncodedFormEntity stringEntity=new UrlEncodedFormEntity(parameters);
                httpPost.setEntity(stringEntity);
                HttpClientBuilder.create().build().execute(httpPost);
                System.out.println(i);
            } catch (IOException e) {
                e.printStackTrace();
            }
        
        }
    }
}
